package org.lex.swing.graph;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;

import org.lex.swing.ActionBuilder;
import org.lex.swing.Swings;
import org.lex.utils.pool.DaemonExecutor;


public class ProgressGraphPane extends JPanel implements ProgressListener {
	static class Run implements Runnable {
		static Random rand = new Random();
		private ProgressModel model = null;
		private int start = 0;

		public Run(ProgressModel model, int start) {
			this.model = model;
			this.start = start;
		}

		public void run() {
			while (true) {
				int step = start + rand.nextInt(100);
				model.addRange(start, step);
				start = step;
				try {
					Thread.sleep(200 + rand.nextInt(300));
				} catch (Exception e) {
				}
			}
		}
	}

	public static void main(String[] args) {
		final DefaultProgressModel model = new DefaultProgressModel();
		// model.addRange( new Range( -10, 17 ) );
		// model.addRange( new Range( 35, 77 ) );
		// model.addRange( new Range( 93, 111 ) );
		Window w = Swings.createWindow(new ProgressGraphPane(model), false);
		// w.setSize( 500, 75 );
		w.setVisible(true);
		model.setMaximum(10000);
		int count = 7;
		int step = (int) (model.getMaximum() / count);
		for (int i = 0; i < count; i++) {
			DaemonExecutor.execute(new Run(model, i + i * step));
		}
	}

	private ProgressGraph view = null;

	public ProgressGraphPane(ProgressModel model) {
		this(model, BasicProgressGraph.WIDTH, BasicProgressGraph.HEIGHT);
	}

	public ProgressGraphPane(ProgressModel model, int width, int height) {
		view = new ProgressGraph(model, width, height);
		view.setBackground(this.getBackground());
		view.getModel().addGraphListener(this);
		this.createDebugMenu();
	}

	public ProgressModel getModel() {
		return view.getModel();
	}

	public void setModel(ProgressModel model) {
		view.getModel().removeGraphListener(this);
		view.setModel(model);
		view.getModel().addGraphListener(this);
	}

	public void createDebugMenu() {
		JPopupMenu popup = new JPopupMenu();
		popup.add(new ActionBuilder("Debug").setActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				Window root = SwingUtilities.getWindowAncestor(ProgressGraphPane.this);
				DebugGraphDialog d = new DebugGraphDialog(root, view.getModel());
				d.setSize(300, 300);
				d.setLocationRelativeTo(root);
				d.setVisible(true);
			}
		}));
		this.setComponentPopupMenu(popup);
	}

	@Override
	public void setBackground(Color bg) {
		super.setBackground(bg);
		if (null != view)
			view.setBackground(bg);
	}

	public void rangesAdded(ProgressEvent e) {
		this.repaint();
	}

	public void rangesRemoved(ProgressEvent e) {
		this.repaint();
	}

	@Override
	public void boundsChanged(ProgressEvent e) {
		this.repaint();
	}

	private Insets insets = new Insets(0, 0, 0, 0);

	@Override
	protected void paintComponent(Graphics g) {
		// FIXME ��ɫ�����ø���Ч�ķ������
		g.setColor(this.getBackground());
		g.fillRect(0, 0, getWidth(), getHeight());
		// -----------------------------------------
		this.insets = this.getInsets(insets);
		int left = this.insets.left;
		int top = this.insets.top;
		view.setSize(getWidth() - left - insets.right, getHeight() - top - insets.bottom);
		g.drawImage(view.getImage(), left, top, this);
		g.dispose();
	}
}
